home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <math.h>
- #include <OSUtils.h>
- #include <QuickDraw.h>
- #include <Sound.h>
-
- #define NEED_MAC_STUFF 1
-
- #include "Ninkasi:C++ util:generic.h"
- #include "Ninkasi:C++ util:complete_window.h"
- #include "ear_defines.h"
- #include "ear_decl.h"
- #include "ear_prototypes.h"
-
- // returns avg of left and right volumes;
- // 256 = max normal vol
- int
- get_current_volume(SndChannelPtr snd_chan)
- {
- SndCommand my_snd_command;
- union {
- long the_volumes;
- short vol[2];
- } vol_data;
- my_snd_command.cmd = getVolumeCmd;
- my_snd_command.param2 = (long) &(vol_data.the_volumes);
- SndDoImmediate(snd_chan,&my_snd_command);
- return (int) (.5*(vol_data.vol[0]+vol_data.vol[1]));
- }
-
- void
- set_volume(int new_volume,SndChannelPtr snd_chan)
- {
- SndCommand my_snd_command;
- union {
- long the_volumes;
- short vol[2];
- } vol_data;
- my_snd_command.cmd = volumeCmd;
- vol_data.vol[0] = new_volume;
- vol_data.vol[1] = new_volume;
- my_snd_command.param2 = vol_data.the_volumes;
- SndDoImmediate(snd_chan,&my_snd_command);
- }
-
- // The first time this routine is called, everything is computed from
- // scratch.
- // On subsequent calls, the default behavior is to simply rescale the
- // floating-point version of the waveform, and the "kind" parameter
- // is ignored.
- // To force a recalculation from scratch, set both have_wave_table
- // and have_temp_wave_table to zero.
- void
- do_waveforms(
- SndChannelPtr *my_snd_chan,
- int kind,
- double amplitude,
- int chans_used,
- unsigned char *wave_table,
- double *temp_storage,
- int wave_table_size)
- {
- dispose_of_chans(chans_used,my_snd_chan);
- //..in case they were already installed
- make_sound_channels(chans_used,init_chan_list,kind_of_chan_list,my_snd_chan);
- if (!have_wave_table) {
- make_wave_table(wave_table,temp_storage,kind,amplitude,wave_table_size,
- !have_temp_wave_table);
- have_wave_table = 1;
- have_temp_wave_table = 1;
- }
- install_waveforms(chans_used,my_snd_chan,wave_table,wave_table_size,kind_of_chan_list);
- }
-
- void
- play_chord(int notes_in_chord,
- SndChannelPtr *my_snd_chan,
- int *note,
- int duration, //-- in half-milliseconds
- int if_wait)
- {
- int delay_ticks,i;
- SndCommand my_snd_cmd;
- OSErr my_err;
-
- set_up_sound();
-
- for (i=0; i<=notes_in_chord-1; i++) {
- my_snd_cmd.cmd = freqDurationCmd;
- my_snd_cmd.param1 = duration;
- my_snd_cmd.param2 = note[i]+pitch_offset;
- my_err = SndDoCommand(my_snd_chan[i],&my_snd_cmd,FALSE);
- if (my_err!=0) {
- bail_out("error playing sound");
- }
- }
- if (if_wait) {
- delay_ticks = duration/33.33333;
- delay_some(delay_ticks);
- wait_until_chan_not_busy(my_snd_chan[notes_in_chord-1],1);
- }
-
- dispose_of_chans(chans_used,my_snd_chan);
- // Let other programs have sound channels. Also, make sure
- // sound channels are available for parts of this program
- // that use other synthesizers other than the wavetable one.
-
- }
-
- void
- wait_until_chan_not_busy(SndChannelPtr my_snd_chan,int max_secs)
- {
- unsigned long count;
- int max_ticks;
- OSErr my_err;
- SCStatus my_sc_status;
- max_ticks = max_secs*60;
- count = 0;
- do {
- my_err = SndChannelStatus(my_snd_chan,sizeof(SCStatus),&my_sc_status);
- delay_some(1); /* 1 tick = 1/60 sec */
- ++count;
- } while(my_sc_status.scChannelBusy && count<max_ticks);
- }
-
- void
- rest(int nhalf_ms)
- {
- delay_some((int) (nhalf_ms/33.33333));
- }
-
- void
- delay_some(int nticks)
- {
- unsigned long delay_ticks,sys_time;
- delay_ticks = nticks;
- Delay(delay_ticks,(long *) &sys_time);
- }
-
- void
- install_waveforms(int nchan,SndChannelPtr *my_snd_chan,
- unsigned char *my_wave_table,int wave_table_size,short *kind_of_chan_list)
- {
- int i;
- SndCommand my_snd_cmd;
- OSErr my_err;
- my_snd_cmd.cmd = waveTableCmd;
- my_snd_cmd.param1 = wave_table_size;
- my_snd_cmd.param2 = (long) my_wave_table;
- for (i=0; i<nchan; i++) {
- if (kind_of_chan_list[i]==waveTableSynth) {
- if (!made_snd_chan[i]) bail_out("channel not made yet in install_waveforms");
- my_err = SndDoCommand(my_snd_chan[i],&my_snd_cmd,FALSE);
- if (my_err!=0) {
- char s[200];
- sprintf(s,"error in install_waveforms, i=%d, my_err=%d, my_snd_chan[i]=%08lx\n",
- (int) i,(int) my_err,(long) my_snd_chan[i]);
- bail_out(s);
- }
- }
- }
- }
-
- void
- make_sound_channels(
- int chans_used,
- long *init_chan_list,
- short *kind_of_chan_list,
- SndChannelPtr *my_snd_chan) /* array of pointers to sound channels */
- {
- int i;
- OSErr my_err;
- dispose_of_chans(chans_used,my_snd_chan);
- for (i=0; i<chans_used; i++) {
- my_snd_chan[i] = NULL; /* tells it I need a new channel allocated on heap */
- my_err = SndNewChannel(&my_snd_chan[i],
- kind_of_chan_list[i],init_chan_list[i],NULL);
- if (my_err!=0) {
- bail_out("error in SndNewChannel\n");
- }
- made_snd_chan[i] = 1;
- }
- }
-
- void
- dispose_of_chans(
- int chans_used,
- SndChannelPtr *my_snd_chan) /* array of pointers to sound channels */
- {
- int i;
- OSErr my_err;
- for (i=0; i<=chans_used-1; i++) {
- if (made_snd_chan[i] && VALID_POINTER(my_snd_chan[i])) {
- my_err = SndDisposeChannel(my_snd_chan[i],(Boolean) 1);
- /* 0=await completion, 1=immediate return */
- made_snd_chan[i] = 0;
- my_snd_chan[i] = (SndChannelPtr) 0;
- }
- }
- }
-
-